/* eslint-disable no-param-reassign */
/* eslint-disable no-continue */
/* eslint-disable no-plusplus */
/* eslint-disable no-shadow */
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-restricted-globals */

// 从主程序中导入接口定义的类型
interface IWorkerMessage {
  tasks: any[];
  resources: any[];
  config: any;
  uiCoordinateData: {
    cellWidth: number;
    cellHeight: number;
  };
}

// 定义需要的接口类型（与主程序中一致）
interface IScheduleTask {
  id: string;
  name: string;
  start: Date;
  end: Date;
  resourceId: string;
  data: Record<string, any>;
}

interface IScheduleResource {
  id: string;
  name: string;
  tasks: IScheduleTask[];
  data: Record<string, any>;
}

interface IResourceViewModel {
  id: string;
  width: number;
  height: number;
  top: number;
  left: number;
  data: IScheduleResource;
}

interface ITaskViewModel {
  id: string;
  originalId: string;
  resourceId: string;
  width: number;
  height: number;
  top: number;
  left: number;
  data: IScheduleTask;
}

self.onmessage = (e: MessageEvent<IWorkerMessage>) => {
  const { tasks, resources, config, uiCoordinateData } = e.data;

  // 重建uiCoordinate对象
  const uiCoordinate = {
    cellWidth: uiCoordinateData.cellWidth,
    cellHeight: uiCoordinateData.cellHeight,
  };

  // 重建Variables常量（与主程序中一致）
  const Variables = {
    time: {
      millisecondOf: {
        millisecond: 1,
        second: 1000,
        minute: 60000,
        hour: 3600000,
        day: 86400000,
        week: 604800000,
      },
    },
  };

  // 构建资源视图模型
  const buildResourceViewModels = (): IResourceViewModel[] => {
    const resourceViewModels: IResourceViewModel[] = [];
    if (resources.length > 0) {
      for (let i = 0; i < resources.length; i++) {
        const resource = resources[i];
        resourceViewModels.push({
          id: resource.id,
          width: config.resourceColumnWidth,
          height: config.resourceBodyRowHeight,
          top: i * config.resourceBodyRowHeight,
          left: 0,
          data: resource,
        });
      }
    }
    return resourceViewModels;
  };

  // 过滤有效任务
  const filterValidTasks = (tasks: any[]): IScheduleTask[] => {
    return tasks.filter((task: IScheduleTask) => {
      // 检查任务的开始时间和结束时间是否有效
      if (task.start >= task.end) {
        return false;
      }
      // 如果任务的结束时间小于全局开始时间，则任务无效
      if (task.end < config.startTime) {
        return false;
      }
      // 如果任务的开始时间大于全局结束时间，则任务无效
      if (task.start > config.endTime) {
        return false;
      }
      return true;
    });
  };

  // 将跨天任务分割成每天的部分
  const splitTaskByDays = (task: IScheduleTask): IScheduleTask[] => {
    const splitTasks: IScheduleTask[] = [];

    // 如果任务不跨天，直接返回原任务
    const taskStart = new Date(task.start);
    const taskEnd = new Date(task.end);

    // 如果开始和结束在同一天，不需要分割
    if (taskStart.toDateString() === taskEnd.toDateString()) {
      return [task];
    }

    // 分割跨天任务
    const currentStart = new Date(taskStart);
    let dayCounter = 0;

    while (currentStart < taskEnd) {
      // 计算当天的结束时间（23:59:59）
      const currentEnd = new Date(currentStart);
      currentEnd.setHours(23, 59, 59, 999);

      // 如果当前结束时间超过了任务结束时间，则使用任务结束时间
      if (currentEnd > taskEnd) {
        currentEnd.setTime(taskEnd.getTime());
      }

      // 创建分割后的任务
      const splitTask: IScheduleTask = {
        ...task,
        id: `${task.id}_part_${dayCounter}`,
        start: new Date(currentStart),
        end: new Date(currentEnd),
      };

      splitTasks.push(splitTask);

      // 设置下一天的开始时间（00:00:00）
      currentStart.setDate(currentStart.getDate() + 1);
      currentStart.setHours(0, 0, 0, 0);
      dayCounter++;
    }

    return splitTasks;
  };

  // 构建任务视图模型
  const buildTaskViewModels = (): ITaskViewModel[] => {
    const taskViewModels: ITaskViewModel[] = [];
    const validTasks = filterValidTasks(tasks);

    if (validTasks.length > 0) {
      // 计算时间范围内的天数
      const startDate = new Date(config.startTime);
      startDate.setHours(0, 0, 0, 0);
      const endDate = new Date(config.endTime);
      endDate.setHours(0, 0, 0, 0);

      for (let i = 0; i < validTasks.length; i++) {
        const task = validTasks[i];
        const resourceIndex = resources.findIndex(
          (resource: any) => resource.id === task.resourceId,
        );

        if (resourceIndex === -1) {
          continue;
        }

        // 处理跨天任务，将其分割成多个部分
        const splitTasks = splitTaskByDays(task);

        splitTasks.forEach(splitTask => {
          // 计算任务日期属性
          const taskStartDate = new Date(splitTask.start);
          taskStartDate.setHours(0, 0, 0, 0);
          const taskEndDate = new Date(splitTask.end);
          taskEndDate.setHours(0, 0, 0, 0);

          // 计算任务在日期轴上的位置
          const daysFromStart = Math.ceil(
            (taskStartDate.getTime() - startDate.getTime()) /
              Variables.time.millisecondOf.day,
          );
          const left =
            config.resourceColumnWidth +
            config.scaleColumnWidth +
            daysFromStart * uiCoordinate.cellWidth;

          // 如果任务跨多天，计算宽度
          const taskDurationDays =
            Math.ceil(
              (taskEndDate.getTime() - taskStartDate.getTime()) /
                Variables.time.millisecondOf.day,
            ) + 1;
          const width = taskDurationDays * uiCoordinate.cellWidth;

          // 计算任务在时间轴上的位置（垂直方向）
          const taskStartHour =
            splitTask.start.getHours() + splitTask.start.getMinutes() / 60;
          const top =
            resourceIndex * config.resourceBodyRowHeight +
            (taskStartHour - config.scaleRange[0]) *
              (uiCoordinate.cellHeight / config.scaleValue);

          // 计算任务高度
          const taskDurationHours =
            (splitTask.end.getTime() - splitTask.start.getTime()) /
            Variables.time.millisecondOf.hour;
          const height =
            taskDurationHours * (uiCoordinate.cellHeight / config.scaleValue);

          taskViewModels.push({
            id: splitTask.id,
            originalId: task.id,
            resourceId: splitTask.resourceId,
            width,
            height,
            top,
            left,
            data: splitTask,
          });
        });
      }
    }

    return taskViewModels;
  };

  // 检查两个任务的时间是否重叠
  const isTimeOverlapping = (
    task1: ITaskViewModel,
    task2: ITaskViewModel,
  ): boolean => {
    // 如果是同一原始任务的不同部分，则不认为是冲突
    if (task1.originalId === task2.originalId) {
      return false;
    }

    return (
      task1.left < task2.left + task2.width &&
      task1.left + task1.width > task2.left &&
      task1.top < task2.top + task2.height &&
      task1.top + task1.height > task2.top
    );
  };

  // 检测任务冲突并分组
  const groupConflictingTasks = (
    taskViewModels: ITaskViewModel[],
  ): ITaskViewModel[][] => {
    const groups: ITaskViewModel[][] = [];
    const visited = new Set<string>();

    taskViewModels.forEach(task => {
      if (visited.has(task.id)) return;

      const group: ITaskViewModel[] = [task];
      visited.add(task.id);

      taskViewModels.forEach(otherTask => {
        if (visited.has(otherTask.id) || task.id === otherTask.id) return;

        // 检查是否为同一资源
        if (task.resourceId !== otherTask.resourceId) return;

        // 检查时间是否重叠
        if (isTimeOverlapping(task, otherTask)) {
          group.push(otherTask);
          visited.add(otherTask.id);
        }
      });

      groups.push(group);
    });

    return groups;
  };

  // 处理冲突任务的显示位置
  const processConflictingTasks = (
    conflictGroups: ITaskViewModel[][],
  ): void => {
    conflictGroups.forEach(group => {
      if (group.length <= 1) return;

      // 按照top位置排序
      group.sort((a, b) => a.top - b.top);

      // 计算每项的宽度
      const singleWidth = group[0].width / group.length;

      // 调整每个任务的位置和宽度
      group.forEach((task: ITaskViewModel, index: number) => {
        task.width = singleWidth;
        task.left += index * singleWidth;
      });
    });
  };

  // 主处理流程
  const resourceViewModels = buildResourceViewModels();
  const taskViewModels = buildTaskViewModels();

  // 检测并处理冲突任务
  const conflictGroups = groupConflictingTasks(taskViewModels);
  processConflictingTasks(conflictGroups);

  // 返回结果
  self.postMessage({ resourceViewModels, taskViewModels });
};
